package com.dataseek.iot.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dataseek.iot.toolikit.common.consts.SysConsts;
import com.dataseek.iot.sys.entity.*;
import com.dataseek.iot.sys.mapper.*;
import com.dataseek.iot.sys.service.SysUserService;
import com.dataseek.iot.sys.vo.SysUserVo;
import com.dataseek.iot.toolikit.common.enums.RspStatusEnum;
import com.dataseek.iot.toolikit.common.util.EncodeUtil;
import com.dataseek.iot.toolikit.common.util.SnowflakeIdWorker;
import com.dataseek.iot.toolkit.auth.entity.SysUser;
import com.dataseek.iot.toolkit.tenant.config.DynamicDataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @discription:
 * @author: Freya.Yan
 * @date: 2022/1/11
 */
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper1, SysUser> implements SysUserService {


    @Autowired
    private TenantSysUserMapper userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private UserDeptMapper userDeptMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private DeptMapper deptMapper;



    @Override
    public SysUserVo queryUser(String UserName, String telephone, String deptName, String roleName, Integer userIdIn, String status, Integer num, Integer size) {
        List<SysUserTable> mapList = new ArrayList<>();
        SysUserVo SysUserVo = new SysUserVo();
        QueryWrapper<TenantSysUser> qw = new QueryWrapper<>();
        if (UserName != null && !UserName.isEmpty()) {
            qw.like("user_name", UserName);
        }
        if (telephone != null && !telephone.isEmpty()) {
            qw.like("telephone", telephone);
        }
        if (status != null && !status.isEmpty()) {
            qw.eq("status", status);
        }
        if (userIdIn != null) {
            qw.eq("user_id", userIdIn);
        }
        List<Long> roleIds = new ArrayList<>();
        List<Long> deptIds = new ArrayList<>();
        if (deptName != null && !deptName.isEmpty()) {
            QueryWrapper<Dept> deptqw = new QueryWrapper<>();
            deptqw.eq("dept_name", deptName);
            Dept dept1 = deptMapper.selectOne(deptqw);
            if (dept1 != null) {
                long id = dept1.getDeptId();
                QueryWrapper<UserDept> deptUserqw = new QueryWrapper<>();
                deptUserqw.eq("dept_id", id);
                List<UserDept> userDepts = userDeptMapper.selectList(deptUserqw);
                if (userDepts.size() > 0) {

                    for (int m = 0; m < userDepts.size(); m++) {
                        Long idsIn = userDepts.get(m).getUserId();
                        roleIds.add(idsIn);
                    }

                }

            }
            if (roleIds.size() > 0) {
                qw.in("user_id", roleIds);
            } else {
                qw.eq("user_id", -1);
            }
        }
        if (roleName != null && !roleName.isEmpty()) {
            QueryWrapper<Role> deptR = new QueryWrapper<>();
            deptR.eq("role_name", roleName);
            Role role1 = roleMapper.selectOne(deptR);
            if (role1 != null) {
                long id = role1.getRoleId();
                QueryWrapper<UserRole> roleUserqw = new QueryWrapper<>();
                roleUserqw.eq("role_id", id);
                List<UserRole> userRoles = userRoleMapper.selectList(roleUserqw);
                if (userRoles.size() > 0) {
                    for (int m = 0; m < userRoles.size(); m++) {
                        Long idsIn = userRoles.get(m).getUserId();
                        deptIds.add(idsIn);
                    }

                }

            }
            if (deptIds.size() > 0) {
                qw.in("user_id", deptIds);
            } else {
                qw.eq("user_id", -1);
            }
        }

        IPage<TenantSysUser> page = new Page<>(num, size);
        List<TenantSysUser> userList = userMapper.selectPage(page, qw).getRecords();
        if (userList.size() > 0) {
            for (int i = 0; i < userList.size(); i++) {
                TenantSysUser user = userList.get(i);
                SysUserTable userTable = new SysUserTable();
                userTable.setTenantCode(user.getTenantCode());
                userTable.setUserId(user.getUserId());
                userTable.setUserName(user.getUserName());
                userTable.setUserPassword(user.getUserPassword());
                userTable.setStatus(user.getStatus());
                userTable.setTelephone(user.getTelephone());
                userTable.setEmail(user.getEmail());
                userTable.setCreateBy(user.getCreateBy());
                userTable.setCreateTime(user.getCreateTime());
                userTable.setUpdateBy(user.getUpdateBy());
                userTable.setUpdateTime(user.getUpdateTime());
                userTable.setUserType(user.getUserType());
                long userId = user.getUserId();
                QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
                userRoleQueryWrapper.eq("user_id", userId);
                UserRole userRoleIn = userRoleMapper.selectOne(userRoleQueryWrapper);
                if (userRoleIn != null) {
                    long roleId = userRoleIn.getRoleId();
                    QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
                    roleQueryWrapper.eq("role_id", roleId);
                    String roleNameIn = roleMapper.selectOne(roleQueryWrapper).getRoleName();
                    userTable.setRoleName(roleNameIn);
                }
                QueryWrapper<UserDept> userDeptQueryWrapper = new QueryWrapper<>();
                userDeptQueryWrapper.eq("user_id", userId);
                UserDept userDept = userDeptMapper.selectOne(userDeptQueryWrapper);
                if (userDept != null) {

                    long deptId = userDept.getDeptId();
                    QueryWrapper<Dept> deptQueryWrapper = new QueryWrapper<>();
                    deptQueryWrapper.eq("dept_id", deptId);
                    String deptNameIn = deptMapper.selectOne(deptQueryWrapper).getDeptName();
                    userTable.setDeptName(deptNameIn);
                }
                mapList.add(userTable);
            }
        }
        SysUserVo.setPage(num);
        SysUserVo.setSize(size);
        SysUserVo.setTotal(page.getTotal());
        SysUserVo.setList(mapList);
        return SysUserVo;
    }


    @Override
    public Integer updateUser(SysUserTable sysUserTable) {
        TenantSysUser tenantSysUser = new TenantSysUser();
        int resultCode = 0;
        String userName = sysUserTable.getUserName();
        QueryWrapper<TenantSysUser> qw = new QueryWrapper<>();
        qw.eq("user_name", userName);
        tenantSysUser.setUserName(sysUserTable.getUserName());
        tenantSysUser.setUserId(sysUserTable.getUserId());
        tenantSysUser.setTenantCode(sysUserTable.getTenantCode());
        tenantSysUser.setStatus(sysUserTable.getStatus());
        tenantSysUser.setTelephone(sysUserTable.getTelephone());
        tenantSysUser.setEmail(sysUserTable.getEmail());
        tenantSysUser.setCreateBy(sysUserTable.getCreateBy());
        tenantSysUser.setUpdateBy(sysUserTable.getUpdateBy());
        tenantSysUser.setUserType(sysUserTable.getUserType());
        resultCode = userMapper.updateById(tenantSysUser);
        long userId = sysUserTable.getUserId();
        String roleName = sysUserTable.getRoleName();
        String deptName = sysUserTable.getDeptName();
        if (deptName != null && !"".equals(deptName)) {
            QueryWrapper<Dept> deptQueryWrapper = new QueryWrapper<>();
            deptQueryWrapper.eq("dept_name", deptName);
            long deptId = deptMapper.selectOne(deptQueryWrapper).getDeptId();
            UserDept userDept = new UserDept();
            userDept.setUserId(userId);
            userDept.setDeptId(deptId);
            userDept.setTenantCode(sysUserTable.getTenantCode());
            QueryWrapper<UserDept> deptUserQueryWrapper = new QueryWrapper<>();
            deptUserQueryWrapper.eq("user_id", userId);
            userDeptMapper.update(userDept, deptUserQueryWrapper);
        }

        if (roleName != null && !"".equals(roleName)) {
            QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
            roleQueryWrapper.eq("role_name", roleName);
            long roleId = roleMapper.selectOne(roleQueryWrapper).getRoleId();
            UserRole userRole = new UserRole();
            userRole.setTenantCode(sysUserTable.getTenantCode());
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            QueryWrapper<UserRole> roleUserQueryWrapper = new QueryWrapper<>();
            roleUserQueryWrapper.eq("user_id", userId);
            resultCode = userRoleMapper.update(userRole, roleUserQueryWrapper);
        }

        return resultCode;
    }

    @Override
    public Integer insertUser(SysUserTable sysUserTable) {
        String tenantCode = DynamicDataSourceContextHolder.getDataSourceKey();
        int resultCode = 0;
        String userName = sysUserTable.getUserName();
        String roleName = sysUserTable.getRoleName();
        String deptName = sysUserTable.getDeptName();
        TenantSysUser tenantSysUser = new TenantSysUser();
        UserRole userRole = new UserRole();
        UserDept userDept = new UserDept();
        QueryWrapper<TenantSysUser> qw = new QueryWrapper<>();
        qw.eq("user_name", userName);
        Integer count = userMapper.selectCount(qw);
        if (count == 0) {
            tenantSysUser.setTenantCode(tenantCode);
            tenantSysUser.setUserName(sysUserTable.getUserName());
            String pw = sysUserTable.getUserPassword();
            if (pw != null && !"".equals(pw)) {
                String encode = EncodeUtil.passwordEncoder(pw);
                tenantSysUser.setUserPassword(encode);
            }
            tenantSysUser.setTelephone(sysUserTable.getTelephone());
            tenantSysUser.setEmail(sysUserTable.getEmail());
            tenantSysUser.setCreateBy(sysUserTable.getCreateBy());
            tenantSysUser.setUpdateBy(sysUserTable.getUpdateBy());
            tenantSysUser.setUserType(SysConsts.USER_TYPE_NORMAL_USER);
            userMapper.insert(tenantSysUser);

            long userId = userMapper.selectOne(qw).getUserId();
            if (roleName != null && !"".equals(roleName)) {
                QueryWrapper<Role> qwRole = new QueryWrapper<>();
                qwRole.eq("role_name", roleName);
                long roleId = roleMapper.selectOne(qwRole).getRoleId();
                userRole.setTenantCode(tenantCode);
                userRole.setRoleId(roleId);
                userRole.setUserId(userId);
                userRole.setRelId(SnowflakeIdWorker.nextId());
                userRoleMapper.insert(userRole);
            }
            if (deptName != null && !"".equals(deptName)) {
                QueryWrapper<Dept> qwDept = new QueryWrapper<>();
                qwDept.eq("dept_name", deptName);
                long deptId = deptMapper.selectOne(qwDept).getDeptId();
                userDept.setTenantCode(tenantCode);
                userDept.setUserId(userId);
                userDept.setDeptId(deptId);
                userDept.setRelId(SnowflakeIdWorker.nextId());
                resultCode = userDeptMapper.insert(userDept);
            }

        } else {
            resultCode = RspStatusEnum.FAIL.getCode();
        }
        return resultCode;
    }

    @Override
    public Integer deleteUser(List<Integer> UserIds) {
        int resultCode = userMapper.deleteBatchIds(UserIds);
        for (int i = 0; i < UserIds.size(); i++) {
            QueryWrapper<UserRole> qwRole = new QueryWrapper<>();
            QueryWrapper<UserDept> qwDept = new QueryWrapper<>();
            long userId = UserIds.get(i);
            qwRole.eq("user_id", userId);
            qwDept.eq("user_id", userId);
            resultCode = userRoleMapper.delete(qwRole);
            resultCode = userDeptMapper.delete(qwDept);
        }
        return resultCode;
    }

    @Override
    public Boolean resetPassword(String tenantCode,String userType,String userName) {
        Boolean result = false;
        if(StringUtils.isEmpty(tenantCode)) {
            //如果是超级管理员
            if(SysConsts.USER_TYPE_SUPER_ADMIN.equals(userType)) {
                DynamicDataSourceContextHolder.setDataSourceKey("master");
            }
            else{
                throw new RuntimeException("目标重置用户非法!");
            }
        }
        else{
            DynamicDataSourceContextHolder.setDataSourceKey(tenantCode);
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encodePassword = passwordEncoder.encode("123456");
        QueryWrapper<SysUser> qw = new QueryWrapper();
        qw.eq("user_name",userName);
        List<SysUser> sysUserList = this.list(qw);
        SysUser sysUserVo = new SysUser();
        for(SysUser sysUser:sysUserList){
            sysUserVo.setUserId(sysUser.getUserId());
            break;
        }
        if(sysUserVo.getUserId()!=null){
            sysUserVo.setPassword(encodePassword);
            result=this.saveOrUpdate(sysUserVo);
        }
        return result;
    }
}
